﻿using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Ymatou.CommonService;
using Ymatou.Counter.Contract;
using Ymatou.Evaluate.Buyer.Model.ApiModel.Request.Query;
using Ymatou.Evaluate.Buyer.Model.ApiModel.Response.Query;
using Ymatou.Evaluate.Buyer.Model.Dto;
using Ymatou.Evaluate.Common;
using Ymatou.Evaluate.Data.Query;
using Ymatou.Evaluate.Entity;
using Ymatou.Evaluate.Service.Buyer.Extensions;
using Ymatou.Evaluate.Service.Buyer.Interface;
using Ymatou.ServiceCenter;
using EvaluateStatus = Ymatou.Evaluate.Buyer.Model.Dto.EvaluateStatus;
using EvaluateType = Ymatou.Evaluate.Buyer.Model.Dto.EvaluateType;

namespace Ymatou.Evaluate.Service.Buyer.Implement
{
    internal class BuyerQueryService : IBuyerQueryService
    {
        /// <summary>
        /// 获取订单评价状态
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public GetOrdersEvalStatusResponse GetOrdersEvalStatus(GetOrdersEvalStatusRequest request)
        {
            var response = new GetOrdersEvalStatusResponse();
            var list = EvaluateQueryData.GetOrderStatusByBuyerIdOrderIds(request.BuyerId, request.OrderIds);
            if (list != null && list.Any())
            {
                response.OrdersEvalStatus =
                    request.OrderIds.Select(
                        o => new OrderEvalStatus {OrderId = o, Status = ConvertStatus(o, list)}).ToList();
            }
            else
            {
                response.OrdersEvalStatus =
                    request.OrderIds.Select(
                        o => new OrderEvalStatus {OrderId = o, Status = EvaluateStatus.NotExists}).ToList();
            }
            return response;
        }

        /// <summary>
        /// 获取买家待评价订单Id列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public GetPendingEvaluateOrdersResponse GetPendingEvaluateOrders(GetPendingEvaluateOrdersRequest request)
        {
            var response = new GetPendingEvaluateOrdersResponse
            {
                OrderIds =
                    EvaluateQueryData.GetOrderIdsByBuyerId(request.BuyerId,
                        request.LastOrderId, request.PageSize)
            };
            return response;
        }

        /// <summary>
        /// 获取买家待评价订单总数
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public GetPendingEvaluateCountResponse GetPendingEvaluateCount(GetPendingEvaluateCountRequest request)
        {
            var response = new GetPendingEvaluateCountResponse
            {
                TotalNum = EvaluateQueryData.GetOrderCountByBuyerIdStatus(request.BuyerId)
            };
            return response;
        }

        /// <summary>
        /// 转换订单评价状态
        /// </summary>
        /// <param name="orderId"></param>
        /// <param name="ordersStatus"></param>
        /// <returns></returns>
        private static EvaluateStatus ConvertStatus(int orderId, List<EvaluateOrderStatus> ordersStatus)
        {
            if (ordersStatus == null || !ordersStatus.Any())
            {
                return EvaluateStatus.NotExists;
            }
            var os = ordersStatus.FirstOrDefault(o => o.OrderId == orderId);
            if (os == null)
            {
                return EvaluateStatus.NotExists;
            }
            switch (os.Status)
            {
                case Entity.EvaluateStatus.Pending:
                    return os.SysTime.Subtract(os.AddTime).Days >= 60 ? EvaluateStatus.Expired : EvaluateStatus.Pending;
                case Entity.EvaluateStatus.Evaluated:
                    return EvaluateStatus.Evaluated;
                default:
                    return EvaluateStatus.Pending;
            }
        }

        /// <summary>
        /// 获取商品评价列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public GetProdEvaluateListResponse GetProdEvaluateList(GetProdEvaluateListRequest request)
        {
            var result = new GetProdEvaluateListResponse();
            var condition = new EvalProdQueryCondition
            {
                PageIndex = request.PageIndex,
                PageSize = request.PageSize,
                ProductId = request.ProductId
            };
            if (request.LastEvalTime.HasValue && request.LastProdEvalId.HasValue)
            {
                condition.EvalTime = request.LastEvalTime.Value.LongTime2DateTime();
                condition.ProdEvalId = request.LastProdEvalId.Value;
            }
            switch (request.EvalTp)
            {
                case EvaluateType.All:
                    condition.Level = EvaluateLevel.All;
                    break;
                case EvaluateType.Top:
                    condition.Level = EvaluateLevel.Top;
                    break;
                case EvaluateType.Mid:
                    condition.Level = EvaluateLevel.Mid;
                    break;
                case EvaluateType.Low:
                    condition.Level = EvaluateLevel.Low;
                    break;
                case EvaluateType.Img:
                    condition.Level = EvaluateLevel.Img;
                    break;
            }

            List<EvaluateImgs> imgs;
            List<EvaluateReply> replies;
            var list = EvaluateQueryData.GetEvaluateProductList(condition, out imgs, out replies);
            if (list != null && list.Any())
            {
                result.EvalList = list.MapProductEvaluate(imgs, replies);
            }

            var score = 0m;
            var ps = GetSummaryByProdId(request.ProductId, ref score);
            result.ProductId = request.ProductId;
            var totalSummary = ps.FirstOrDefault(p => p.SummaryTp == request.EvalTp);
            result.TotalCount = totalSummary != null ? totalSummary.TotalNum : 0;
            return result;
        }

        /// <summary>
        /// 获取商品评价汇总
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public GetProductSummaryResponse GetProductSummary(GetProductSummaryRequest request)
        {
            var score = 0m;
            var result = new GetProductSummaryResponse
            {
                ProductId = request.ProductId,
                Summary = GetSummaryByProdId(request.ProductId, ref score),
                Score = score
            };
            return result;
        }

        private static List<ProductSummary> InitProdSummary()
        {
            var prodSummary = new List<ProductSummary>
            {
                new ProductSummary {Desc = "全部", SummaryTp = EvaluateType.All, TotalNum = 0},
                new ProductSummary {Desc = "好评", SummaryTp = EvaluateType.Top, TotalNum = 0},
                new ProductSummary {Desc = "中评", SummaryTp = EvaluateType.Mid, TotalNum = 0},
                new ProductSummary {Desc = "差评", SummaryTp = EvaluateType.Low, TotalNum = 0},
                new ProductSummary {Desc = "有图", SummaryTp = EvaluateType.Img, TotalNum = 0}
            };
            return prodSummary;
        }

        private static List<ProductSummary> GetSummaryByProdId(string productId, ref decimal score)
        {
            var prodSummary = InitProdSummary();

            var dic = GetGroupCounterList(EvaluateConfig.CounterGood, new List<string> { productId });
            if (dic != null && dic.ContainsKey(productId))
            {

                var summary = dic[productId];
                var evalTotalNum = 0;

                ProductSummary summaryItem = null;
                foreach (var kv in summary)
                {
                    if (!kv.Key.Equals("evaluate_pic") && !kv.Key.Equals("evaluate_score"))
                    {
                        evalTotalNum += kv.Value;
                    }

                    switch (kv.Key)
                    {
                        case "evaluate_good":
                            summaryItem = prodSummary.FirstOrDefault(p => p.SummaryTp == EvaluateType.Top);
                            break;
                        case "evaluate_normal":
                            summaryItem = prodSummary.FirstOrDefault(p => p.SummaryTp == EvaluateType.Mid);
                            break;
                        case "evaluate_bad":
                            summaryItem = prodSummary.FirstOrDefault(p => p.SummaryTp == EvaluateType.Low);
                            break;
                        case "evaluate_pic":
                            summaryItem = prodSummary.FirstOrDefault(p => p.SummaryTp == EvaluateType.Img);
                            break;
                        case "evaluate_score":
                            score = Util.DecimalConvert(kv.Value, false);
                            break;
                    }
                    if (kv.Key.Equals("evaluate_score")) continue;
                    if (summaryItem != null) summaryItem.TotalNum = kv.Value;
                }
                summaryItem = prodSummary.FirstOrDefault(p => p.SummaryTp == EvaluateType.All);
                if (summaryItem != null) summaryItem.TotalNum = evalTotalNum;
            }
            return prodSummary;
        }

        /// <summary>
        /// 获取计数
        /// </summary>
        /// <param name="counter">好评数:evaluate_good;中评数:evaluate_normal;差评数:evaluate_bad;有图数:evaluate_pic;商品评分:evaluate_score</param>
        /// <param name="targetIds">商品ID列表</param>
        /// <returns></returns>
        private static Dictionary<string, Dictionary<string, int>> GetGroupCounterList(string counter,
            List<string> targetIds)
        {
            if (targetIds == null || targetIds.Count <= 0) return null;
            var request = new GetGroupCounterListRequest()
            {
                AppId = EvaluateConfig.CounterAppId,
                Counter = counter,
                TargetIds = targetIds
            };
            ApplicationLog.Debug(string.Format("api/get/group/list调用获取计数接口请求参数:{0}", JsonConvert.SerializeObject(request)));
            try
            {
                var response = ServiceClient.Execute<GetGroupCounterListRequest, GetGroupCounterListResponse>(request);
                if (response != null && response.Code == StatusCode.Success)
                {
                    ApplicationLog.Debug(string.Format("api/get/group/list调用获取计数接口请求响应:{0}", JsonConvert.SerializeObject(response)));
                    return response.Data;
                }
            }
            catch (Exception ex)
            {
                
                ApplicationLog.Error("api/get/group/list调用获取计数接口", ex);
            }
            return null;
        }
    }
}
